# 该文件为代码的编译和推so流程
# encoding=utf-8

__author__ = 'lee'

import os
import sys
from constants import *
from json.decoder import JSONDecoder
from utils import CommandExecute, Logger
from utils import command_execute, parse_json

class BuildCodeHandler():
    def __init__(self, cmd_exe: CommandExecute, config: JSONDecoder):
        """
        cmd_exe: 远程linux命令执行工具
        target: 编译执行目标
        rebuild: 是否快速重编译
        coverage: 是否产生覆盖率报告
        """
        self.cmd_exe = cmd_exe
        self.config = config
        self.code_path = self.config['personal']['code']['path']

    def _mkdir(self, path):
        isExits = os.path.exists(path)
        if not isExits:
            os.makedirs(path)
            Logger.info(f"path {path} make successfully")
        else:
            Logger.info(f"path {path} already exits")

    def process(self, targets: list, fast_rebuild=False, coverage=False, push_so=False):
        subsystem_config = self.config['subsystem']
        coverage_config = subsystem_config['coverage_config']
        so_targets = subsystem_config['so_paths']['build_target']
        so_out_paths = subsystem_config['so_paths']['out_path']
        so_push_path = subsystem_config['so_paths']['push_path']
        subsystem_test_name = subsystem_config['test_target_name']
        test_out_path = subsystem_config['test_out_path']
        if push_so:
            # 如果需要push_so, 就编译so_target
            cmd =  f'cd {self.code_path}&&{DEFAULT_BUILD_CMD} --build-target'
            for so_target in so_targets:
                cmd = f'{cmd} {so_target}'
            if fast_rebuild:
                cmd = f'{cmd} --fast-rebuild'
            build_result = self.cmd_exe.execute_no_log(cmd)
            if not build_result:
                Logger.error(f'compile {so_target} failed')
                sys.exit()
            # 编译完成之后直接push_so让板子重启
            # 先将so拉下来存到本地的temp目录
            for so_out_path in so_out_paths:
                cmd = f'find {so_out_path}'
                result = self.cmd_exe.execute_no_print(cmd)
                if len(result):
                    self._mkdir('temp')
                    so_name = so_out_path.split('/')[-1]
                    local_file = f'temp/{so_name}'
                    self.cmd_exe.sftp_get(result[0].strip('\n'), local_file)
                else:
                    Logger.error(
                        f'{so_out_path} not exits, please check code and execute process')
                    sys.exit()

            # 将编译所得的so全部推送至开发板中并重启开发板
            command_execute(HDC_MOUNT)
            for so_out_path in so_out_paths:
                so_name = so_out_path.split('/')[-1]
                command_execute(f'{HDC_FILE_SEND} temp/{so_name} {so_push_path}')
            command_execute(HDC_REBOOT)

        cmd = f'cd {self.code_path} && {DEFAULT_BUILD_CMD} --build-target'
        for test_suite in targets:
            # 编译所有测试套列表
            cmd = f'{cmd} {test_suite}'
        if coverage:
            cmd = f'{cmd} --gn-args {coverage_config}=true'
        if fast_rebuild:
            cmd = f'{cmd} --fast-rebuild'
        build_result = self.cmd_exe.execute_no_log(cmd)
        if not build_result:
            Logger.error(f'Compile {test_suite} test suite failed')
            sys.exit()

        self._mkdir('testsuites')
        for test_suite in targets:
            # 将编译所得测试套全部拷贝至本地
            if test_suite == subsystem_test_name:
                # 考虑一种特殊情况
                # 测试套是子系统全量用例
                result = self.cmd_exe.execute_no_print(f'find {test_out_path} -type f')
                for test_suite_path in result:
                    test_suite_name = test_suite_path.strip('\n').split('/')[-1]
                    self.cmd_exe.sftp_get(test_suite_path.strip('\n'), f'./testsuites/{test_suite_name}')
                break
            else:
                # 单独的测试套
                command = f'find {test_out_path} -name {test_suite}'
                result = self.cmd_exe.execute_no_print(command)
                if len(result):
                    local_file = f'./testsuites/{test_suite}'
                    self.cmd_exe.sftp_get(result[0].strip('\n'), local_file)


if __name__ == '__main__':
    config = parse_json('config.json')
    host = config['personal']['ssh']['host']
    port = config['personal']['ssh']['port']
    username = config['personal']['ssh']['username']
    password = config['personal']['ssh']['password']
    ce = CommandExecute(host, port, username, password)
    targets = ['ace_engine_test']
    bc = BuildCodeHandler(ce, config)
    bc.process(targets, fast_rebuild=True, push_so=True)
